#include "glwidget.h"
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>

GLWidget::GLWidget(QWidget *parent)
    : QOpenGLWidget(parent)
{
    // 初始化旋转角度
    angle = 0.0f;

    // 创建定时器
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [this]() { update(); }); // 使用 Lambda 表达式
    timer->start(16); // 大约60帧每秒
}

GLWidget::~GLWidget()
{
    // 删除顶点数组对象和顶点缓冲区对象
    makeCurrent(); // 确保当前上下文有效
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(2, vbo);
    doneCurrent(); // 释放上下文
}

void GLWidget::initializeGL()
{
    // 初始化OpenGL函数
    initializeOpenGLFunctions();

    // 设置清除颜色为黑色
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    // 创建顶点数据和颜色数据
    GLfloat vertices[9] = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.5f, 0.0f
    };

    GLfloat colors[9] = {
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 1.0f
    };

    // 创建顶点数组对象和顶点缓冲区对象
    glGenVertexArrays(1, &vao);
    glGenBuffers(2, vbo);

    // 绑定顶点数组对象
    glBindVertexArray(vao);

    // 绑定顶点缓冲区对象
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(0);

    // 绑定颜色缓冲区对象
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(1);

    // 创建着色器程序
    program.addShaderFromSourceCode(QOpenGLShader::Vertex,
        "attribute vec3 vertex;\n"
        "attribute vec3 color;\n"
        "varying vec3 vColor;\n"
        "uniform mat4 model;\n"
        "uniform mat4 view;\n"
        "uniform mat4 projection;\n"
        "void main()\n"
        "{\n"
        "    gl_Position = projection * view * model * vec4(vertex, 1.0);\n"
        "    vColor = color;\n"
        "}"
    );
    program.addShaderFromSourceCode(QOpenGLShader::Fragment,
        "varying vec3 vColor;\n"
        "void main()\n"
        "{\n"
        "    gl_FragColor = vec4(vColor, 1.0);\n"
        "}"
    );
    program.link();
    program.bind();
}

void GLWidget::resizeGL(int w, int h)
{
    // 设置视口大小
    glViewport(0, 0, w, h);
}

void GLWidget::paintGL()
{
    // 清除颜色缓冲区
    glClear(GL_COLOR_BUFFER_BIT);

    // 设置旋转矩阵
    QMatrix4x4 model;
    model.setToIdentity();
    model.rotate(angle, 0.0f, 1.0f, 0.0f); // 绕y轴旋转

    // 设置视图矩阵
    QMatrix4x4 view;
    view.setToIdentity();
    view.translate(0.0f, 0.0f, -3.0f); // 将视图向后移动

    // 设置投影矩阵
    QMatrix4x4 projection;
    projection.setToIdentity();
    projection.perspective(45.0f, width() / (float)height(), 0.1f, 100.0f);

    // 设置矩阵
    program.setUniformValue("model", model);
    program.setUniformValue("view", view);
    program.setUniformValue("projection", projection);

    // 绑定顶点数组对象
    glBindVertexArray(vao);

    // 绘制三角形
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // 更新旋转角度
    angle += 1.0f;
}